# Process module
Function ProcessExec {
    param(
        [String]$FilePath,
        [String]$Arguments,
        [String]$WorkingDirectory
    )
    $ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo 
    $ProcessInfo.FileName = $FilePath
    if ($WorkingDirectory.Length -eq 0) {
        $ProcessInfo.WorkingDirectory = $PWD
    }
    else {
        $ProcessInfo.WorkingDirectory = $WorkingDirectory
    }
    $ProcessInfo.Arguments = $Arguments
    $ProcessInfo.UseShellExecute = $false ## use createprocess not shellexecute
    $Process = New-Object System.Diagnostics.Process 
    $Process.StartInfo = $ProcessInfo 
    try {
        $Process.Start()|Out-Null
    }
    catch {
        Write-Host -ForegroundColor Red "exec $FilePath error: $_"
        return -1
    }

    $Process.WaitForExit()
    return $Process.ExitCode
}

Function ArgvToArgs {
    param(
        [string[]]$ArgumentList
    )
    $newargs = ""
    for ($i = 0; $i -lt $ArgumentList.Count; $i++) {
        [string]$arg = $ArgumentList[$i]
        if ($arg.Contains(" ") -or $arg.Contains("\t")) {
            $newargs += "`"$arg`" "
        }
        else {
            $newargs += "$arg "
        }
    }
    return $newargs
}

Function ProcessNoArgv {
    param(
        [string]$FilePath
    )
    return ProcessExec -FilePath $FilePath
}

Function ProcessArgv {
    param(
        [string]$FilePath,
        [string[]]$ArgumentList
    )
    $arguments = ArgvToArgs -ArgumentList $ArgumentList
    return ProcessExec -FilePath $FilePath -Arguments $arguments
}

Function ProcessArgvDir {
    param(
        [string]$FilePath,
        [string[]]$ArgumentList,
        [string]$Workdir
    )
    $arguments = ArgvToArgs -ArgumentList $ArgumentList
    return ProcessExec -FilePath $FilePath -Arguments $arguments -WorkingDirectory $Workdir
}